package org.jkuang.qstar.index.parser;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/**
 * 语法解析器，检查语法的合法性
 * 
 * 若语法合法，则将语法拆分为最简单的 多个 OR列表，每个or条件内都是AND操作符连接，例如： A OR (B AND C)
 * 
 * @author jkuang 2012年11月17日
 *
 */
public class ParserParam {

	private List<Set<Integer>> list = new ArrayList<Set<Integer>>();
	private List<Set<Integer>> filter = new ArrayList<Set<Integer>>();

	public List<Set<Integer>> getResult() {
		return list;
	}

	public List<Set<Integer>> getFilter() {
		return filter;
	}

	/**
	 * 
	 * @param param
	 */
	public ParserParam(Integer param) {

		if (param >= 0) {
			Set<Integer> params = new TreeSet<Integer>();
			params.add(param);
			this.list.add(params);
		}

	}

	/**
	 * 
	 * @param param
	 * @return
	 */
	public ParserParam addOR(Integer param) {
		if (param >= 0) {
			Set<Integer> params = new TreeSet<Integer>();
			params.add(param);
			this.list.add(params);
		}
		return this;
	}

	/**
	 * 
	 * @param param
	 * @return
	 */
	public ParserParam addAND(Integer param) {
		// 如果查询的表达式不存在
		if (param < 0) {
			this.list.clear();
		} else {
			for (Set<Integer> q0 : this.list) {
				q0.add(param);
			}
		}
		return this;
	}

	/**
	 * 
	 * @param param
	 * @return
	 */
	public ParserParam OR(ParserParam param) {
		for (Set<Integer> vl : param.list) {
			if (vl.size() > 0) {
				this.list.add(vl);
			}
		}
		return this;

	}

	/**
	 * 
	 * @param param
	 * @return
	 */
	public ParserParam AND(ParserParam param) {
		List<Set<Integer>> list = new ArrayList<Set<Integer>>();
		for (Set<Integer> q0 : this.list) {
			if (q0.size() == 0) {
				continue;
			}
			for (Set<Integer> q1 : param.list) {
				if (q1.size() == 0) {
					continue;
				}
				Set<Integer> set = new TreeSet<Integer>();
				set.addAll(q0);
				set.addAll(q1);
				list.add(set);
			}
		}
		this.list = list;
		return this;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		int i = 0;
		for (Set<Integer> set : this.list) {
			if (i++ > 0) {
				buffer.append(" OR ");
			}
			int k = 0;
			for (Integer q : set) {
				if (k++ == 0) {
					buffer.append(" ").append(q);
				} else {
					buffer.append(" AND ").append(q);
				}
			}
		}
		return buffer.toString();
	}
}
